using System;
using System.Collections.Generic;

public class myPoint3D
{
  //The x,y,z coordinates of this point.
  public double X, Y, Z;

  public myPoint3D()
  {
      X = 0;
      Y = 0;
      Z = 0;
  }

  public myPoint3D(double _X, double _Y, double _Z)
  {
      X = _X;
      Y = _Y;
      Z = _Z;
  }

  /// Caclul le barycentre d'une liste de point nombre inconnu
  public static myPoint3D AveragePoint(params myPoint3D[] points)
  {
      if (points == null) return null;

      myPoint3D average = new myPoint3D(0,0,0);

      int nbPoints = points.Length;

      foreach(myPoint3D p in points)
      {
          average += p;
      }

      average /= nbPoints;

      return average;
  }

  public static myPoint3D Sum(params myPoint3D[] points)
  {
      myPoint3D sum = new myPoint3D(0, 0, 0);
      for (int i = 0; i < points.Length; i++)
      {
          sum += points[i];
      }
      return sum;
  }

  public static myPoint3D MiddlePoint(myPoint3D p1, myPoint3D p2)
  {
      return (p1 + p2) / 2;
  }

  public double Distance(myPoint3D p1, myPoint3D p2)
  {
      myPoint3D p = p2-p1;

      return Math.Sqrt(p.X * p.X + p.Y * p.Y + p.Z * p.Z);
  }

  public static bool operator == (myPoint3D p1, myPoint3D p2)
  {
      return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
  }

  public static bool operator != (myPoint3D p1, myPoint3D p2)
  {
      return !(p1 == p2);
  }

  public static myPoint3D operator - (myPoint3D p1, myPoint3D p2)
  {
      myPoint3D p = new myPoint3D();
      p.X = p1.X - p2.X;
      p.Y = p1.Y - p2.Y;
      p.Z = p1.Z - p2.Z;

      return p;
  }
   
  public static myPoint3D operator + (myPoint3D p1, myPoint3D p2)
  {
      myPoint3D p = new myPoint3D();
      p.X = p1.X + p2.X;
      p.Y = p1.Y + p2.Y;
      p.Z = p1.Z + p2.Z;
      return p;
  }

  public static myPoint3D operator + (myPoint3D p1, myVector3D v)
  {
      myPoint3D p = new myPoint3D(0,0,0);
      p.X = p1.X + v.dX;
      p.Y = p1.Y + v.dY;
      p.Z = p1.Z + v.dZ;
      return p;
  }

  public static myPoint3D operator / (myPoint3D p1, double val)
  {
      myPoint3D p = new myPoint3D(0, 0, 0);
      p.X = p1.X / val;
      p.Y = p1.Y / val;
      p.Z = p1.Z / val;
      return p;
  }

  public static myPoint3D operator *( myPoint3D p1, double val )
  {
      myPoint3D p = new myPoint3D(0, 0, 0);
      p.X = p1.X * val;
      p.Y = p1.Y * val;
      p.Z = p1.Z * val;
      return p;
  }

  public static myPoint3D operator *( double val, myPoint3D p )
  {
      return p * val;
  }

  public static myPoint3D operator /( double val, myPoint3D p)
  {
      return p / val;
  }

  public myPoint3D GetClone()
  {
      myPoint3D clone = new myPoint3D(this.X, this.Y, this.Z);
      return clone;
  }

}
